﻿using System.Text.Encodings.Web;
using System.Text.Json.Serialization;
using System.Text.Json;
using CommunityToolkit.Diagnostics;

namespace JackProjectTemplate.Shared.Utilities
{
    public static class JSON
    {
        public static readonly JsonSerializerOptions DefaultJsonSerializerOptions;

        public static readonly JsonWriterOptions DefaultJsonWriterOptions;

        public static readonly JsonStringEnumConverter DefaultStringEnumConverter;

        static JSON()
        {
            DefaultJsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web)
            {
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
            };
            DefaultJsonWriterOptions = new JsonWriterOptions
            {
                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
            };
            DefaultStringEnumConverter = new JsonStringEnumConverter(JsonNamingPolicy.CamelCase);
            DefaultJsonSerializerOptions.Converters.Add(DefaultStringEnumConverter);
            DefaultJsonSerializerOptions.Converters.Add(System.Text.Json.Serialization.Metadata.JsonMetadataServices.TimeSpanConverter);
        }

        public static string Serialize<T>(this T value, JsonSerializerOptions? options = null)
        {
            return JsonSerializer.Serialize(value, options ?? DefaultJsonSerializerOptions);
        }

        public static T? Deserialize<T>(this string value, JsonSerializerOptions? options = null)
        {
            return JsonSerializer.Deserialize<T?>(value, options ?? DefaultJsonSerializerOptions);
        }

        public static T DeserializeRequired<T>(this string value) where T : class
        {
            T? val = JsonSerializer.Deserialize<T?>(value, DefaultJsonSerializerOptions);
            Guard.IsNotNull(val, "result");
            return val;
        }
    }
}
